let _isEmpty = require('lodash.isempty');
let _isFinite = require('lodash.isfinite');
let _isPlainObject = require('lodash.isplainobject');
let CryptoJS = require('crypto-js');
let moment = require('moment');
let _isEqual = require('lodash.isequal');
let Tools = {
    deepCopyObj(obj) {
        let result = {};
        for (let key in obj) {
            result[key] = _isPlainObject(obj[key]) ? this.deepCopyObj(obj[key]) : obj[key]
        }
        return result
    }, objDeepCopy(source) {
        let sourceCopy = source instanceof Array ? [] : {};
        for (let item in source) {
            sourceCopy[item] = typeof source[item] === "object" ? objDeepCopy(source[item]) : source[item]
        }
        return sourceCopy
    }, sortedUniq(arr) {
        if (!this.isArray(arr)) {
            return null
        }
        let newArr = [];
        arr.forEach((ele, i, self) => {
            if (i == 0) {
                newArr.push(ele)
            } else {
                if (this.isString(ele) || this.isNumber(ele) || this.isBoolean(ele)) {
                    if (ele !== self[i - 1]) {
                        newArr.push(ele)
                    }
                } else {
                    if (!_isEqual(ele, self[i - 1])) {
                        newArr.push(ele)
                    }
                }
            }
        });
        return newArr
    }, checkTelephone(val) {
        const reg = /^(\+?0?86\-?)?1[345789]\d{9}$/;
        return reg.test(val)
    }, isObject(value) {
        let type = typeof value;
        return !!value && (type === "object" || type === "function")
    }, isObjectLike(value) {
        return !!value && typeof value === "object"
    }, isBoolean(value) {
        let boolTag = "[object Boolean]";
        let objectToString = Object.prototype.toString;
        return value === true || value === false || (this.isObjectLike(value) && objectToString.call(value) === boolTag)
    }, isString(value) {
        let stringTag = "[object String]";
        let objectToString = Object.prototype.toString;
        return typeof value === "string" || (!this.isArray(value) && this.isObjectLike(value) && objectToString.call(value) === stringTag)
    }, isNumber(value) {
        let numberTag = "[object Number]";
        let objectToString = Object.prototype.toString;
        return typeof value === "number" || (this.isObjectLike(value) && objectToString.call(value) === numberTag)
    }, isArray(value) {
        let arrTag = "[object Array]";
        let objectToString = Object.prototype.toString;
        return (Array.isArray && Array.isArray(value)) || objectToString.call(value) === arrTag
    }, isFunction(value) {
        let objectToString = Object.prototype.toString;
        let funcTag = "[object Function]", genTag = "[object GeneratorFunction]";
        let tag = this.isObject(value) ? objectToString.call(value) : "";
        return tag === funcTag || tag === genTag
    }, isRegExp(value) {
        let objectToString = Object.prototype.toString;
        let regexpTag = "[object RegExp]";
        return this.isObject(value) && objectToString.call(value) === regexpTag
    }, isDate(value) {
        let dateTag = "[object Date]";
        let objectToString = Object.prototype.toString;
        return this.isObjectLike(value) && objectToString.call(value) === dateTag
    }, isNull(value) {
        return value === null
    }, isUndefined(value) {
        return value === undefined
    }, _isNaN(value) {
        return this.isNumber(value) && value != +value
    }, _isEmpty(value) {
        return (this.isString(value) && _isEmpty(value)) || this.isNull(value) || this.isUndefined(value)
    }, getExtensionName(path) {
        if (typeof path == "string") {
            let index = path.lastIndexOf(".");
            return path.slice(index + 1)
        }
    }, _toNumber(value) {
        if (this.isString(value)) {
            let valueParsed = parseFloat(value);
            if (isNaN(valueParsed) || valueParsed.toString() !== value) {
                value = NaN
            } else {
                value = valueParsed
            }
        }
        return this.isNumber(value) ? value : NaN
    }, _isNumber(value) {
        let number = this._toNumber(value);
        return !isNaN(number) && _isFinite(number)
    }, encryptForWeb(val) {
        let md5 = CryptoJS.MD5(val);
        let utf8 = CryptoJS.enc.Utf8.parse(md5);
        let base64 = CryptoJS.enc.Base64.stringify(utf8) || utf8.toString(CryptoJS.enc.Base64);
        return base64
    }, encryptForApp(val) {
        let md5 = CryptoJS.MD5(val);
        let base64 = CryptoJS.enc.Base64.stringify(md5) || md5.toString(CryptoJS.enc.Base64);
        return base64
    }, encryptOnlyBase64(val) {
        let utf8 = CryptoJS.enc.Utf8.parse(val);
        let base64 = CryptoJS.enc.Base64.stringify(utf8) || utf8.toString(CryptoJS.enc.Base64);
        return base64
    }, decrypt(val) {
        let base64 = CryptoJS.enc.Base64.parse(val);
        let utf8 = CryptoJS.enc.Utf8.stringify(base64);
        return utf8
    }, formatDate(date, format = 'YYYY-MM-DD HH:mm:ss', isUTC = false) {
        const _date = isUTC ? moment.utc(date).local() : moment(date);
        return _date.format(format)
    }, isEmail(value) {
        const regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/;
        return regEmail.test(value)
    }
};
module.exports = {Tools}